package com.autumn.evaluator;

//
// * 表示 call 委托（用户自定义函数）的一个参数 通过 this[]属于获取(VB则为item方法)，索引从1开始，
//

import com.autumn.evaluator.annotation.ParamRegister;
import com.autumn.evaluator.exception.FunctionParamException;
import com.autumn.util.StringUtils;

import java.io.Serializable;

/**
 * 函数参数
 */
public class FunctionParam implements Serializable {

    /**
     * 序列号
     */
    private static final long serialVersionUID = 5475332525619464250L;

    /**
     * 实例化 FunParam 类新实例
     *
     * @param orderID      顺序
     * @param name         参数名称
     * @param caption      参数说明
     * @param defaultValue 默认值
     * @param paramType    参数类型
     */
    public FunctionParam(int orderID, String name, String caption, Variant defaultValue, int paramType) {
        if (StringUtils.isNullOrBlank(name)) {
            name = "DefaultName";
        }
        if (this.caption == null) {
            this.caption = "";
        }

        this.setOrderID(orderID);
        this.setName(name);
        this.caption = caption;
        this.setDefaultValue(defaultValue);
        this.setParamType(paramType);
    }

    /**
     * 实例化 FunParam 类新实例
     *
     * @param orderID
     * @param parseContext
     * @param paramFunc
     * @param funParam
     */
    public FunctionParam(int orderID, IParseContext parseContext, java.util.function.Function<IParseContext, Variant> paramFunc, FunctionParam funParam) {
        this.parseContext = parseContext;
        this.paramFunc = paramFunc;
        this.setOrderID(orderID);
        if (funParam != null) {
            this.caption = funParam.getCaption();
            this.setName(funParam.getName());
            this.setParamType(funParam.getParamType());
            this.setDefaultValue(funParam.getDefaultValue());
        } else {
            this.caption = "";
            this.setName("DefaultName");
            this.setParamType(VariantType.NULL);
        }
    }

    private IParseContext parseContext;
    private java.util.function.Function<IParseContext, Variant> paramFunc;

    /**
     * 获取参数顺序
     */
    private int orderID;

    public final int getOrderID() {
        return orderID;
    }

    private void setOrderID(int value) {
        orderID = value;
    }

    /**
     * 获取参数名称
     */
    private String name;

    public final String getName() {
        return name;
    }

    private void setName(String value) {
        name = value;
    }

    private String caption = "";

    /**
     * 获取参数说明
     */
    public final String getCaption() {
        if (this.getAttribute() != null) {
            // this.getAttribute().language = this.getParentFunParams().FUNCTION.Language;
            // this.getAttribute().configPath = this.getParentFunParams().FUNCTION.ConfigPath;
            return this.getAttribute().caption();
        }
        return this.caption;
    }

    private ParamRegister attribute = null;
    private boolean isLoadAttribute = false;

    private ParamRegister getAttribute() {
        if (!this.isLoadAttribute) {
            if (this.getParentFunParams() != null && this.getParentFunParams().getFunction() != null) {
                this.isLoadAttribute = true;
                if (this.getParentFunParams().getFunction().getCall() != null) {
                    // Object[] Params = this.getParentFunParams().FUNCTION.call.Method.GetCustomAttributes(ParamRegister.class, false);
                    // Set<Class<?>> types;
                    // List<ParamRegister> Params = new ArrayList();
                    // try {
                    //    types = PackageUtils.getPackageAnnotationClass("com.autumn.evaluator.functions", ParamRegister.class);
                    //    for(Class<?> clazz : types) {
                    //        ParamRegister[] annoArray = clazz.getAnnotationsByType(ParamRegister.class);
                    //        Params.addAll(Arrays.asList(annoArray));
                    //    }
                    // } catch (IOException e) {
                    //    e.printStackTrace();
                    // }

                    ParamRegister[] params = getParentFunParams().getFunction().getFunClass().getAnnotationsByType(ParamRegister.class);


                    if (params != null && params.length > 0) {
                        for (ParamRegister par : params) {
                            if (par.name() != null) {
                                if (par.name().toLowerCase().equals(this.getName().toLowerCase())) {
                                    this.attribute = ((par instanceof ParamRegister) ? par : null);
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }
        return this.attribute;
    }

    /**
     * 获取参数类型
     */
    private int paramType;

    public final int getParamType() {
        return paramType;
    }

    private void setParamType(int value) {
        paramType = value;
    }

    /**
     * 获取参数值默认值
     */
    private Variant defaultValue;

    public final Variant getDefaultValue() {
        return defaultValue;
    }

    private void setDefaultValue(Variant value) {
        defaultValue = value;
    }

    /**
     * 读取参数值
     *
     * @return
     */
    public final Variant readValue() {
        if (this.paramFunc != null) {
            Variant value = this.paramFunc.apply(this.parseContext);
            if (value.isNull() && !"".equals(this.getDefaultValue().getValue().toString())) {
                return this.getDefaultValue();
            }
            if (this.getParamType() != VariantType.NULL && value.isNull()) {
                String message = String.format("第 %s 参数 [%s] 不能为空值。", (new Integer(this.getOrderID())).toString(), this.getName());
                throw new FunctionParamException(this.getParentFunParams().getFunction().getName(), this.getName(), message);
            } else {
                if (this.getParamType() != VariantType.NULL && !((this.getParamType() & value.getVariantType()) == value.getVariantType())) {
                    String message = String.format("第 %s 个参数 [%s]  的类型必须是 [%s] 。", (new Integer(this.getOrderID())).toString(), this.getName(), this.getParamType());
                    throw new FunctionParamException(this.getParentFunParams().getFunction().getName(), this.getName(), message);
                }
            }
            return value;
        } else {
            return this.getDefaultValue();
        }
    }

    /**
     * 获取父级参数集合
     */
    private FunctionParams parentFunParams;

    public final FunctionParams getParentFunParams() {
        return parentFunParams;
    }

    private void setParentFunParams(FunctionParams value) {
        parentFunParams = value;
    }

    /**
     * 设置函数
     *
     * @param params 参数集合
     */
    public final void setParam(FunctionParams params) {
        this.setParentFunParams(params);
    }
}